package com.shootingGame.physics.collisionReactionClasses.base
{
	import com.shootingGame.renderableClasses.GameObject;
	import com.shootingGame.renderableClasses.MobileObject;
	import com.shootingGame.weaponsClasses.ordinance.Ordinance;
	
	import flash.display.MovieClip;
	import flash.geom.Rectangle;
	
	//Each collider will have a ref to an instance of this type.
	//This class maintains a list of general and specific collision types with the various kinds of other objects.
	//Any object type that can sometimes have a different state that affects reactions should be added as a separate collision type
	//for e.g. PLAYER and SHILEDED_PLAYER will be considered as two completely different colliding objects by a ORDINANCE collider.
	
	
	public class CollisionEffects extends MovieClip
	{
		public static const BOUNCE : String = "bounce";
		public static const EXPIRE : String = "expire";
		public static const PERPENDICULAR_ZERO : String = "perpendicular_zero";
		public static const TAKE_DAMAGE : String  = "take_damage";
		public static const NONE : String  = "";
		
		public static const PARAMETER_NAME : String = "parameter_name";
		public static const PARAM_RECT : String = "param_rect";
		public static const PARAM_CIRCLE : String = "param_circle";
//		public static const PARAM_WALL_RECT : String = "param_wall_rect";
		
		public var reactions_ToWall : Array ;
		public var reactions_ToPlayer : Array;
		public var reactions_ToOrdinance : Array;
		
		public var owner : GameObject;
		private var unresolvedCollisions : Array;
		public var ownerColliderType : String;
		private var parameterObject : Object;
		
		public function CollisionEffects(owner:GameObject, ownerColliderType:String, reactions_ToWall:Array = null, reactions_ToPlayer:Array = null, reactions_ToOrdinance:Array = null)
		{
			this.owner = owner;
			this.ownerColliderType = ownerColliderType;
			this.reactions_ToWall = reactions_ToWall;
			this.reactions_ToPlayer = reactions_ToPlayer;
			this.reactions_ToOrdinance = reactions_ToOrdinance;
			unresolvedCollisions = new Array();
		}
		
		public function resolveCollisions() : void {
			var obj:Object;
			
			if(unresolvedCollisions.length > 0)
				obj = unresolvedCollisions[unresolvedCollisions.length-1] as Object;
				if(obj.name == PARAMETER_NAME){
					parameterObject = obj;
					react(unresolvedCollisions[unresolvedCollisions.length-2] as GameObject);
				}
				else
					react(obj as GameObject);
			while(unresolvedCollisions.length > 0)
				unresolvedCollisions.pop();
		}
		
		virtual protected function react(collidee:GameObject) : void {
			var collidee_CollisionEffects:CollisionEffects;
			if(collidee.collisionEffects){
					collidee_CollisionEffects = collidee.collisionEffects;
					switch (collidee_CollisionEffects.ownerColliderType){
						case Colliders.WALL:
							reactToWall(collidee);
							break;
						case Colliders.PLAYER:
							reactToPlayer(collidee);
							break;
						case Colliders.ORDINANCE:
							reactToOrdinance(collidee);
							break;
						default:
							break;
					}
				}
		}
		
		virtual protected function reactToPlayer(collidee:GameObject) : void {
			if(reactions_ToPlayer.length > 0){
				var i : int;
				var n : int = reactions_ToPlayer.length;
				for(i = 0; i < n; i++) {
					switch (reactions_ToPlayer[i].toString()){
						case BOUNCE:
							bounce(collidee);
							break;
						case EXPIRE:
							expire();
							break;
						case PERPENDICULAR_ZERO:
							perpendicular_Zero(collidee);
							break;
						default:
							break;
					}
				}
			}			
		}
		
		virtual protected function reactToWall(collidee:GameObject) : void {
			if(reactions_ToWall.length > 0){
				var i : int;
				var n : int = reactions_ToWall.length;
				for(i = 0; i < n; i++) {
					switch (reactions_ToWall[i].toString()){
						case BOUNCE:
							bounce(collidee);
							break;
						case EXPIRE:
							expire();
							break;
						case PERPENDICULAR_ZERO:
							perpendicular_Zero(collidee);
							break;
						default:
							break;
					}
				}
			}
		}
		
		virtual protected function reactToOrdinance(collidee:GameObject) : void {
			if(ownerColliderType == Colliders.WALL)
				return;
				
			if(reactions_ToOrdinance.length > 0){
				var i : int;
				var n : int = reactions_ToOrdinance.length;
				for(i = 0; i < n; i++) {
					switch (reactions_ToOrdinance[i].toString()){
						case BOUNCE:
							bounce(collidee);
							break;
						case EXPIRE:
							expire();
							break;
						case PERPENDICULAR_ZERO:
							perpendicular_Zero(collidee);
							break;
						case TAKE_DAMAGE:
							take_Damage(collidee);
						default:
							break;
					}
				}
			}
		}
		
		
		virtual public function addCollision(gameObject:GameObject, params:Object = null) : void {
			unresolvedCollisions.push(gameObject);
			if(params){;
				params.name = PARAMETER_NAME;
				unresolvedCollisions.push(params);
			}
		}
		
		virtual protected function bounce(collidee:GameObject) : void {
			
		}
		
		virtual protected function expire() : void {
			owner.isExpired = true;
		}
		
		virtual protected function perpendicular_Zero(collidee:GameObject) : void {
			if(parameterObject)
				if(parameterObject[PARAM_RECT]){
					var rect:Rectangle = parameterObject[PARAM_RECT] as Rectangle;
//					trace("hitSomething");
					if(rect.left > owner.memoryX && rect.right > owner.memoryX){
						if((owner as MobileObject).thrustX > 0){
							(owner as MobileObject).thrustX = 0;
							owner.memoryX = rect.left - owner.getCollidablePart().width/2.0;
//							trace("hitRight");
						}
//						trace((owner as MobileObject).thrustX);
					}
					if(rect.right < owner.memoryX && rect.left < owner.memoryX){
						if((owner as MobileObject).thrustX < 0){
							(owner as MobileObject).thrustX = 0;
							owner.memoryX = rect.right + owner.getCollidablePart().width/2.0;
//							trace("hitLeft");
						}
					}
					
					if(rect.top > owner.memoryY && rect.bottom > owner.memoryY){
						if((owner as MobileObject).thrustY > 0){
							(owner as MobileObject).thrustY = 0;
							owner.memoryY = rect.top - owner.getCollidablePart().height/2.0;
//							trace("hitbottom");
						}
					}
					if(rect.top < owner.memoryY && rect.bottom < owner.memoryY){
						if((owner as MobileObject).thrustY < 0){
							(owner as MobileObject).thrustY = 0;
							owner.memoryY = rect.bottom + owner.getCollidablePart().height/2.0;
						}
//						trace("hitTop");
					}
				}
		}
		
		virtual protected function take_Damage(collidee:GameObject) : void {
			owner.hitPoints -= (collidee as Ordinance).weaponInfo.damage;
		}
		
		

	}
}